package crypt

import (
	"bytes"
	"gitee.com/filters/utils/errv"
	"reflect"
)

var (
	CfbTooShortFail        = errv.New(10001, "密钥的key要大于16位")
	CryptKeynotFound       = errv.New(10002, "没有找到加密的Key")
	ObfNotMultipleSizeFail = errv.New(10003, "data is not a multiple of the block size")
	NotFoundCryptType      = errv.New(10004, "没有找到加密的类型")
	NotFountVariableType =  errv.New(10005, "非该类型的数据")
	JwtTokenIsValid =  errv.New(10006, "token失效")
)

// Crypt 加密解密
type Crypt interface {
	//SetCryptKey 设置key
	SetCryptKey(key string) error

	//ExistCryptKey 是否存在key
	ExistCryptKey() bool

	//Encrypt 加密
	Encrypt(data []byte) (string, error)

	//Decrypt 解密
	Decrypt(data string) (interface{}, error)
}

var cryptList = []Crypt{
	&CbcCrypt{},
	&CfbCrypt{},
	&ObfCrypt{},
	&JwtCrypt{},
}

// NewCrypt ...
func NewCrypt(data Crypt, key string) (Crypt,error) {
	if len(key) < 16 {
		return nil, CfbTooShortFail
	}
	value := reflect.ValueOf(data)
	for _, crypt := range cryptList {
		if value.Type().AssignableTo(reflect.TypeOf(crypt)) {
			crypt.SetCryptKey(key)
			return crypt,nil
		}
	}
	return nil, NotFoundCryptType
}

// PKCS7Padding 补码 ‘AES加密数据块分组长度必须为128bit(byte[16])，密钥长度可以是128bit(byte[16])、192bit(byte[24])、256bit(byte[32])中的任意一个。
func PKCS7Padding(ciphertext []byte, blocksize int) []byte {
	padding := blocksize - len(ciphertext)%blocksize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(ciphertext, padtext...)
}

// PKCS7UnPadding 去码
func PKCS7UnPadding(origData []byte) []byte {
	length := len(origData)
	unpadding := int(origData[length-1])
	return origData[:(length - unpadding)]
}
